package com.congwulin.wechat.util.interfaces;

import com.congwulin.wechat.entity.common.SuperVO;
import com.congwulin.wechat.util.service.bill.BillDeleteService;
import com.congwulin.wechat.util.service.RedisLockService;
import com.congwulin.wechat.util.VOTsCheck;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public abstract class AbstractBillService {


    private static final Logger Log = LoggerFactory.getLogger(BillDeleteService.class);

    /**
     * 一主多子实体保存数据库器
     */
    private IBillPersistent dao;

    /**
     * 一主多子实体抽象服务构造函数
     *
     * @param dao 一主多子实体保存数据库器
     */
    public AbstractBillService(IBillPersistent dao) {
        this.dao = dao;
    }

    /**
     * 检查对应实体的时间戳和数据库是否一致
     *
     * @param values 实体类和实体列表的映射
     */
    protected void checkTs(Map<Class<?>, List<SuperVO>> values) {
        VOTsCheck checker = new VOTsCheck();
        Set<Map.Entry<Class<?>, List<SuperVO>>> set = values.entrySet();
        for (Map.Entry<Class<?>, List<SuperVO>> entry : set) {
            List<SuperVO> list = entry.getValue();
            int size = list.size();
            SuperVO[] vos = new SuperVO[size];
            vos = list.toArray(vos);
            if (size > 0) {
                checker.check(vos, vos[0].getTableName());
            }
        }
    }

    /**
     * 获取单据数据库保存器
     *
     * @return 单据数据库保存器
     */
    protected IBillPersistent getDAO() {
        return this.dao;
    }

    /**
     * 对实体列表进行加锁
     *
     * @param values  实体类和实体列表的映射
     */
    protected Map<String,String> lock(Map<Class<?>, List<SuperVO>> values) {
        RedisLockService lock = new RedisLockService();
        List<String> ids = new ArrayList<String>();
        Set<Map.Entry<Class<?>, List<SuperVO>>> set = values.entrySet();
        for (Map.Entry<Class<?>, List<SuperVO>> entry : set) {
            List<SuperVO> list = entry.getValue();
            int size = list.size();
            SuperVO[] vos = new SuperVO[size];
            vos = list.toArray(vos);
            for(SuperVO vo:vos){
                ids.add(vo.getId());
            }
        }
        return lock.lockWithTimeout(ids.toArray(new String[0]),2000L,2000L);
    }

    /**
     * 对实体列表进行解锁
     *
     * @param lockname  分布式锁名称的映射
     */
    protected boolean unlock(Map<String,String> lockname) {
        RedisLockService lock = new RedisLockService();
        boolean flag = lock.releaseLock(lockname);
        return flag;
    }
}
